package com.zlyx.easy.socket.core;

import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.Protocol;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.transport.AioQuickServer;
import org.smartboot.socket.transport.AioSession;

import com.zlyx.easy.core.utils.ObjectUtils;
import com.zlyx.easy.socket.core.supports.AbstractMsgHandlerFactory;
import com.zlyx.easy.socket.interfaces.IMsgHandler;

/**
 * AIO方式处理TCP消息工厂
 * 
 * @author 赵光
 * @Description: AIO方式处理TCP消息工厂
 * @date 2018年11月14日
 */
public class AioTcpMsgHandlerFactory extends AbstractMsgHandlerFactory implements MessageProcessor<String> {

	private AioQuickServer<String> server;

	public AioTcpMsgHandlerFactory(int port, float size, IMsgHandler<?> handler) throws Exception {
		super(port, size, handler);
		server = new AioQuickServer<String>(this.PORT, new PrivateProtocol(), this);
		server.setBannerEnabled(false);
		server.start();
	}

	@Override
	public void closeServer() throws Exception {
		if (this.server != null) {
			server.shutdown();
		}
	}

	@Override
	public void process(AioSession<String> session, String msg) {
		try {
			InetAddress address = session.getRemoteAddress().getAddress();
			byte[] res = doHandler(address, msg);
			if (ObjectUtils.isNotEmpty(res)) {
				session.write(new String(res));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void stateEvent(AioSession<String> session, StateMachineEnum stateMachineEnum, Throwable throwable) {

	}

	public class PrivateProtocol implements Protocol<String> {

		private static final int INT_LENGTH = 4;

		@Override
		public String decode(ByteBuffer data, AioSession<String> session, boolean eof) {
			if (data.remaining() < INT_LENGTH)
				return null;
			return Charset.forName("UTF-8").decode(data).toString();
		}

		@Override
		public ByteBuffer encode(String s, AioSession<String> session) {
			return ByteBuffer.wrap(s.getBytes());
		}
	}

	@Override
	public boolean doBlock() throws Exception {
		return false;
	}
}
